import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import make_classification
from sklearn.preprocessing import StandardScaler
from mpl_toolkits.mplot3d import Axes3D

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

def visualize_pca():
    # 生成示例数据
    X, y = make_classification(
        n_samples=1000,
        n_features=20,
        n_informative=5,
        n_redundant=5,
        n_classes=3,
        random_state=42
    )

    # 数据标准化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)

    # 第一阶段：5维PCA分析
    pca5 = PCA(n_components=5)
    X_pca5 = pca5.fit_transform(X_scaled)

    # 第二阶段：3维PCA分析
    pca3 = PCA(n_components=3)
    X_pca3 = pca3.fit_transform(X_scaled)

    # 创建图形
    fig = plt.figure(figsize=(18, 6))

    # 5维方差解释图
    ax1 = fig.add_subplot(131)
    ax1.bar(range(5), pca5.explained_variance_ratio_, alpha=0.7, label='各主成分方差')
    ax1.plot(np.cumsum(pca5.explained_variance_ratio_), 'r-o', label='累计方差')
    ax1.set_title('5维PCA方差解释率')
    ax1.set_xlabel('主成分')
    ax1.set_ylabel('方差解释率')
    ax1.legend()
    ax1.grid(True, alpha=0.3)

    # 3维散点图
    ax2 = fig.add_subplot(132, projection='3d')
    scatter = ax2.scatter(
        X_pca3[:, 0], X_pca3[:, 1], X_pca3[:, 2],
        c=y, cmap='viridis', alpha=0.7
    )
    ax2.set_title('3维PCA可视化')
    ax2.set_xlabel(f'PC1 ({pca3.explained_variance_ratio_[0]*100:.1f}%)')
    ax2.set_ylabel(f'PC2 ({pca3.explained_variance_ratio_[1]*100:.1f}%)')
    ax2.set_zlabel(f'PC3 ({pca3.explained_variance_ratio_[2]*100:.1f}%)')

    # 2维散点图（PC1 vs PC2） - 使用相同的颜色映射
    ax3 = fig.add_subplot(133)
    ax3.scatter(X_pca3[:, 0], X_pca3[:, 1], c=y, cmap='viridis', alpha=0.7)
    ax3.set_title('2维PCA投影 (PC1 vs PC2)')
    ax3.set_xlabel(f'PC1 ({pca3.explained_variance_ratio_[0]*100:.1f}%)')
    ax3.set_ylabel(f'PC2 ({pca3.explained_variance_ratio_[1]*100:.1f}%)')
    ax3.grid(True, alpha=0.3)

    # 添加统一的颜色条
    plt.colorbar(scatter, ax=[ax2, ax3], label='类别')

    plt.tight_layout()
    plt.show()

    # 打印关键信息
    print("\n5维PCA分析结果:")
    print(f"解释方差比例: {pca5.explained_variance_ratio_}")
    print(f"累计方差解释率: {np.sum(pca5.explained_variance_ratio_):.3f}")

    print("\n3维PCA分析结果:")
    print(f"解释方差比例: {pca3.explained_variance_ratio_}")
    print(f"累计方差解释率: {np.sum(pca3.explained_variance_ratio_):.3f}")

if __name__ == "__main__":
    visualize_pca()
